<?php

    #-------------------------------------------------------------#
	# This file is part of the Tekuna MVC Microframework for PHP. #
	# (c) 2009 Niels Jäckel <niels.jaeckel@tekuna.org>            #
	# Please visit http://tekuna.org/ for more information.       #
	#                                                             #
	# This software is licensed under the MIT License. Please     #
	# view the LICENSE file for the full text of this license.    #
    #-------------------------------------------------------------#


	Tekuna :: load('org.tekuna.core.filter.TekunaFilter');


	/**
	 * The FilterChain filter allows to apply multiple filters in
	 * successively on one request value. The constructor awaites
	 * multiple parameters that are all TekuaFilter implementations.
	 * The filter() method applies these filters one after another.
	 */

	class FilterChain implements TekunaFilter {

		protected $arrFilters = array();


		/**
		 * Constructor to build a new filter chain out of a bunch
		 * of given TekunaFilters. Parameters are accepted as much
		 * as you provide, but at least one.
		 *
		 * @param TekunaFilter $objFilter(1)
		 * @param TekunaFilter $objFilter(2)
		 *                     ...
		 * @param TekunaFilter $objFilter(n)
		 */

		public function __construct() {

			$iNumArgs = func_num_args();

			// check argument count
			if ($iNumArgs < 1) {

				throw new OutOfRangeException('The construction of a filter chain requires at least one filter object argument.');
			}

			// check argument types
			for ($i = 0; $i < $iNumArgs; $i++) {

				// get the nth argument
				$mArgument = func_get_arg($i);

				// check if the argument is an object of type TekunaFilter
				if (is_object($mArgument) && $mArgument instanceof TekunaFilter) {

					// add filter object to the filter list
					$this -> arrFilters[] = $mArgument;
				}
				else {

					throw new InvalidArgumentException("Argument #$i is not an object of type TekunaFilter.");
				}
			}
		}


		/**
		 * Apply all the registered filters to a given input
		 *
		 * @param mixed $mInput the unfiltered input
		 * @return mixed the multiple filtered output
		 */

		public function filter($mInput) {

			// iterate all filters
			foreach ($this -> arrFilters as $objFilter) {

				// apply each filter method to the given input
				$mInput = $objFilter -> filter($mInput);
			}

			// return the multiple-filtered input
			return $mInput;
		}
	}
